package ldkxingzhe.l365calendar.dao;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.support.annotation.NonNull;

import java.util.ArrayList;
import java.util.List;

import ldkxingzhe.l365calendar.model.NoteEntity;

/**
 * 表note 的dao
 * Created by ke on 16-1-30.
 */
public class NoteDao {

    private L365CalendarOpenHelper helper;
    public NoteDao(Context context){
        helper = L365CalendarOpenHelper.getInstance(context);
    }

    /**
     * 插入一条实体记录
     */
    public void insert(@NonNull NoteEntity entity){
        helper.getWritableDatabase().insertOrThrow(L365CalendarOpenHelper.TABLE_NOTE, null, generateContentValues(entity));
    }

    private ContentValues generateContentValues(@NonNull NoteEntity entity) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(L365CalendarOpenHelper.CREATED, entity.getCreated());
        contentValues.put(L365CalendarOpenHelper.NOTE_DEADLINE, entity.getDeadline());
        contentValues.put(L365CalendarOpenHelper.NOTE_FINISH_TIME, entity.getFinishTime());
        contentValues.put(L365CalendarOpenHelper.NOTE_PRIORITY, entity.getPriority());
        contentValues.put(L365CalendarOpenHelper.NOTE_STATE, entity.getState());
        contentValues.put(L365CalendarOpenHelper.NOTE_TAG, entity.getTags());
        contentValues.put(L365CalendarOpenHelper.NOTE_TITLE, entity.getTitle());
        contentValues.put(L365CalendarOpenHelper.UUID, entity.getUuid());
        contentValues.put(L365CalendarOpenHelper.MODIFIED, entity.getModified());
        return contentValues;
    }

    NoteEntity getNoteEntity(Cursor cursor){
        NoteEntity noteEntity = new NoteEntity();
        noteEntity.set_id(cursor.getInt(cursor.getColumnIndex(L365CalendarOpenHelper.ID)));
        noteEntity.setCreated(cursor.getLong(cursor.getColumnIndex(L365CalendarOpenHelper.CREATED)));
        noteEntity.setDeadline(cursor.getLong(cursor.getColumnIndex(L365CalendarOpenHelper.NOTE_DEADLINE)));
        noteEntity.setPriority(cursor.getInt(cursor.getColumnIndex(L365CalendarOpenHelper.NOTE_PRIORITY)));
        noteEntity.setState(cursor.getInt(cursor.getColumnIndex(L365CalendarOpenHelper.NOTE_STATE)));
        noteEntity.setTags(cursor.getString(cursor.getColumnIndex(L365CalendarOpenHelper.NOTE_TAG)));
        noteEntity.setTitle(cursor.getString(cursor.getColumnIndex(L365CalendarOpenHelper.NOTE_TITLE)));
        noteEntity.setUuid(cursor.getString(cursor.getColumnIndex(L365CalendarOpenHelper.UUID)));
        noteEntity.setModified(cursor.getLong(cursor.getColumnIndex(L365CalendarOpenHelper.MODIFIED)));
        return noteEntity;
    }

    Cursor selectAll(){
        return helper.getReadableDatabase().rawQuery("SELECT * FROM " + L365CalendarOpenHelper.TABLE_NOTE, null);
    }

    public List<NoteEntity> getAllData(){
        List<NoteEntity> resultList = new ArrayList<>();
        Cursor cursor = selectAll();
        while (cursor.moveToNext()){
            resultList.add(getNoteEntity(cursor));
        }
        cursor.close();
        return resultList;
    }

    public void delete(int id){
        String where = L365CalendarOpenHelper.ID + "=" + id;
        helper.getWritableDatabase().delete(L365CalendarOpenHelper.TABLE_NOTE, where, null);
    }

    public void update(@NonNull NoteEntity entity){
        String where = L365CalendarOpenHelper.ID + "=" + entity.get_id();
        helper.getWritableDatabase().update(L365CalendarOpenHelper.TABLE_NOTE,
                generateContentValues(entity),
                where, null);
    }



    private Cursor queryByWhere(String[] projection, String where, String[] selectionArgs){
        return helper.getReadableDatabase()
                .query(L365CalendarOpenHelper.TABLE_NOTE, projection, where, selectionArgs,
                        null, null, null);
    }

    public List<NoteEntity> getSomeDayNote(long millSeconds){
        List<NoteEntity> result = new ArrayList<>();
        String where = "DATE(" + L365CalendarOpenHelper.NOTE_DEADLINE  + "/1000 , \'unixepoch\')" +
                " >= DATE(" + millSeconds / 1000 + ", \'unixepoch\', \'start of day\', \'+1 day\') AND DATE("
                + L365CalendarOpenHelper.CREATED + "/1000, \'unixepoch\') <= DATE(" + millSeconds / 1000
                + ", \'unixepoch\', \'start of day\', \'+1 day\')";
        Cursor cursor = queryByWhere(getAllProjection(), where, null);
        while (cursor.moveToNext()){
            result.add(getNoteEntity(cursor));
        }
        cursor.close();
        return result;
    }

    private String[] getAllProjection() {
        if(projection == null){
            projection = new String[]{
                    L365CalendarOpenHelper.ID, L365CalendarOpenHelper.CREATED, L365CalendarOpenHelper.MODIFIED,
                    L365CalendarOpenHelper.UUID, L365CalendarOpenHelper.NOTE_DEADLINE, L365CalendarOpenHelper.NOTE_FINISH_TIME,
                    L365CalendarOpenHelper.NOTE_PRIORITY, L365CalendarOpenHelper.NOTE_STATE, L365CalendarOpenHelper.NOTE_TAG,
                    L365CalendarOpenHelper.NOTE_TITLE
            };
        }
        return projection;
    }

    private String[] projection;

    <T> void update(int id, String columnName, T newValue){
        String where = L365CalendarOpenHelper.ID + "=" + id;
        ContentValues contentValues = new ContentValues();
        if(newValue instanceof String){
            contentValues.put(columnName, (String)newValue);
        }else if(newValue instanceof Integer){
            contentValues.put(columnName, (Integer)newValue);
        }else if(newValue instanceof Long){
            contentValues.put(columnName, (Long)newValue);
        }
        helper.getWritableDatabase().update(L365CalendarOpenHelper.TABLE_NOTE, contentValues, where, null);
    }

    public void updateModified(int id, long newValue){
        update(id, L365CalendarOpenHelper.MODIFIED, newValue);
    }

    public void updateState(int id, int newValue){
        update(id, L365CalendarOpenHelper.NOTE_STATE, newValue);
    }

    public void updatePriority(int id, int newValue){
        update(id, L365CalendarOpenHelper.NOTE_PRIORITY, newValue);
    }
    public void updateFinishTime(int id, long newValue){
        update(id, L365CalendarOpenHelper.NOTE_FINISH_TIME, newValue);
    }
    public void updateDeadline(int id, long newValue){
        update(id, L365CalendarOpenHelper.NOTE_DEADLINE, newValue);
    }
    public void updateTitle(int id, String newValue){
        update(id, L365CalendarOpenHelper.NOTE_TITLE, newValue);
    }
}
